package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.constants.article.ArticleConstants;
import com.heima.feigns.AdminFeign;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.common.dtos.ResponseResult;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;

    @Autowired
    AdminFeign adminFeign;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 计算热点文章
     */
    @Override
    public void computeHotArticle() {
        //todo 查询前五天的所有文章
        String date = LocalDateTime.now().minusDays(5).
                format(DateTimeFormatter.ofPattern("yyyy-MM-dd 00:00:00"));
        List<ApArticle> articleList = apArticleMapper.selectArticleByDate(date);
        //todo 计算热点文章分值
        List<HotArticleVo> hotArticleVoList=computeArticleScore(articleList);

        //TODO 将热点文章缓存到redis中
        cacheTagToRedis(hotArticleVoList);
    }

    /**
     * 将热点文章缓存到redis中
     * @param hotArticleVoList
     */
    private void cacheTagToRedis(List<HotArticleVo> hotArticleVoList) {
        //todo 查询所有频道列表
        ResponseResult result = adminFeign.findAll();
        if (result!=null&&result.getCode()==0){
            List<AdChannel> adChannelList = JSON.parseArray(
                    JSON.toJSONString(result.getData()),
                    AdChannel.class);
            //todo 遍历频道列表集合，帅选当前频道下的文章
            adChannelList.forEach(adChannel -> {
                List<HotArticleVo> hotArticleVoList1 = hotArticleVoList.stream()
                        .filter(hotArticleVo ->    //todo 当前频道下的文章列表
                                adChannel.getId().equals(hotArticleVo.getChannelId()))
                        .collect(Collectors.toList());
                sortAndCache(hotArticleVoList1,ArticleConstants.HOT_ARTICLE_FIRST_PAGE+adChannel.getId());
            });
        }

        //todo 推荐的文章列表 __all__ 推荐的tag对应key
        sortAndCache(hotArticleVoList, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + ArticleConstants.DEFAULT_TAG);

    }

    /**
     * 文章缓存到redis中，排序取出前30条
     * @param hotArticleVoList
     * @param cachekey
     */
    private void sortAndCache(List<HotArticleVo> hotArticleVoList, String cachekey) {
        hotArticleVoList=hotArticleVoList.stream()
                .sorted(Comparator.comparing(HotArticleVo::getScore).reversed())
                .limit(30).collect(Collectors.toList());

        redisTemplate.opsForValue()
                .set(cachekey,JSON.toJSONString(hotArticleVoList));
    }

    /**
     * 计算热点文章分值
     * @param articleList
     * @return
     */
    private List<HotArticleVo> computeArticleScore(List<ApArticle> articleList) {
        //todo 定义返回的集合
        return articleList.stream().map(apArticle -> {
            HotArticleVo hotArticleVo = new HotArticleVo();
            BeanUtils.copyProperties(apArticle,hotArticleVo);
            //todo 计算文章分值算法
            Integer score = computeScore(apArticle);
            hotArticleVo.setScore(score);
            return hotArticleVo;
        }).collect(Collectors.toList());
    }

    /**
     * 计算文章分值算法
     * @param apArticle
     * @return
     */
    private Integer computeScore(ApArticle apArticle) {
        int score=0;
        //todo 计算阅读量的分值 *1
        if (apArticle.getViews()!=null){
            score += apArticle.getViews()* ArticleConstants.HOT_ARTICLE_VIEW_WEIGHT;
        }
        //todo 计算点赞分值*3
        if (apArticle.getLikes()!=null){
            score +=apArticle.getLikes()*ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT;
        }
        //todo 计算评论*5
        if (apArticle.getComment()!=null){
            score +=apArticle.getComment()*ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT;
        }
        //todo 计算收藏*8
        if (apArticle.getCollection()!=null){
            score +=apArticle.getCollection()*ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT;
        }
        return score;
    }


}
